/*
 * 项目名称:    wms-app-xinpu
 * 创建人员:    DongPeng
 * 创建时间:    2023-02-28
 * copyright(c) 2022 无锡星智数服科技有限公司
 */
package org.jeecg.modules.dock.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.business.warehouse.service.IWmsInReceiptTaskService;
import org.jeecg.modules.dock.client.SapRequestClient;
import org.jeecg.modules.dock.config.SpringContextHolder;
import org.jeecg.modules.dock.constant.SystemConstants;
import org.jeecg.modules.dock.entity.DockDataReceiveRecord;
import org.jeecg.modules.dock.entity.dto.response.SapBaseResponseDTO;
import org.jeecg.modules.dock.enums.DockDataStatus;
import org.jeecg.modules.dock.enums.SapInterfaceTypeEnum;
import org.jeecg.modules.dock.handler.SapDataHandler;
import org.jeecg.modules.dock.mapper.DockDataReceiveRecordMapper;
import org.jeecg.modules.dock.service.SapDataDockingService;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * SAP数据对接服务实现类
 *
 * @author DongPeng
 * @version 1.0.0
 * @date 2023-02-28
 * @description 类描述
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SapDataDockingServiceImpl implements SapDataDockingService {


    private final Map<String, SapDataHandler> SAP_DATA_HANDLER_SET = new HashMap<>();

    private final SapRequestClient sapRequestClient;

    private final IWmsInReceiptTaskService iWmsInReceiptTaskService;


    @PostConstruct
    public void init() {
        Map<String, SapDataHandler> beansOfType = SpringContextHolder.getBeansOfType(SapDataHandler.class);
        Collection<SapDataHandler> values = beansOfType.values();
        for (SapDataHandler handler : values) {
            SapInterfaceTypeEnum type = handler.type();
            if (ObjectUtil.isEmpty(type)) {
                log.warn("初始化SAP处理器");
                continue;
            }
            if (!StrUtil.equals(type.getSource(), SystemConstants.SAP)) {
                log.warn("SAP处理器 {} 配置错误，数据来源错误,处理器类型:{}", handler.getClass().getName(), type);
                continue;
            }
            SAP_DATA_HANDLER_SET.put(type.getCode(), handler);
            log.info("加载SAP数据处理器 业务代码:{} 工序代码:{} 接口名称:{} 处理类:{}", type.getCode(), type.getCode(), type.getRemark(), handler.getClass().getName());
        }
    }

    @Override
    public List<? extends SapBaseResponseDTO> dealData(String business, List<String> list) {
        //记录信息
        DockDataReceiveRecord dockDataReceiveRecord = new DockDataReceiveRecord();
        dockDataReceiveRecord.setBusinessCode(business);
        HttpServletRequest httpServletRequest = SpringContextUtils.getHttpServletRequest();
        httpServletRequest.setAttribute(SystemConstants.AttachKey.RECEIVE,dockDataReceiveRecord);
        log.info("WMS实时接收到的数据是:{} ", list);
        log.info("开始处理SAP业务码:{} 对应业务数据:{}", business, list);
        SapDataHandler sapDataHandler = SAP_DATA_HANDLER_SET.get(business);
        if (sapDataHandler == null) {
            log.info("未找到SAP业务码:{} 对应业务处理器", business);
            dockDataReceiveRecord.setStatus(DockDataStatus.FAILURE);
            SapBaseResponseDTO response = SapBaseResponseDTO.buildResponse(false, "WMS系统数据处理异常,未找到处理器");
            dockDataReceiveRecord.setResultCode(response.getResult());
            dockDataReceiveRecord.setResultData(response.getMessage());
            //保存异常交互记录
//            dockDataReceiveRecordMapper.insert(dockDataReceiveRecord);
            List<SapBaseResponseDTO> result = new ArrayList<>();
            result.add(response);
            return result;
        }
        //根据业务码，执行对应的handler业务处理
        List<? extends SapBaseResponseDTO> responseList = sapDataHandler.handleData(list);
        long errorCount = responseList.stream().map(SapBaseResponseDTO::getResult).filter(res -> StrUtil.equals(SapBaseResponseDTO.ERROR, res)).count();
        if (errorCount == 0) {
            dockDataReceiveRecord.setStatus(DockDataStatus.SUCCESS);
            dockDataReceiveRecord.setResultCode(responseList.get(0).getResult());
            dockDataReceiveRecord.setResultData(responseList.get(0).getMessage());
        } else if (errorCount == responseList.size()) {
            dockDataReceiveRecord.setStatus(DockDataStatus.FAILURE);
            dockDataReceiveRecord.setResultCode(responseList.get(0).getResult());
            dockDataReceiveRecord.setResultData(responseList.get(0).getMessage());
        } else {
            dockDataReceiveRecord.setStatus(DockDataStatus.PART_SUCCESS);
            List<? extends SapBaseResponseDTO> collect = responseList.stream().filter(res -> StrUtil.equals(SapBaseResponseDTO.ERROR, res.getResult())).collect(Collectors.toList());
            dockDataReceiveRecord.setResultCode(collect.get(0).getResult());
            dockDataReceiveRecord.setResultData(collect.get(0).getMessage());
        }
        return responseList;
    }

}
